package cn.iocoder.yudao.module.eval.controller.admin.announcement;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.module.eval.controller.admin.announcement.vo.*;
import cn.iocoder.yudao.module.eval.dal.dataobject.announcement.EvalAnnouncementDO;
import cn.iocoder.yudao.module.eval.service.announcement.EvalAnnouncementService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

@Tag(name = "管理后台 - 公告发布")
@RestController
@RequestMapping("/eval/announcement")
@Validated
public class EvalAnnouncementController {

    @Resource
    private EvalAnnouncementService announcementService;

    @PostMapping("/create")
    @Operation(summary = "创建公告发布")
    @PreAuthorize("@ss.hasPermission('eval:announcement:create')")
    public CommonResult<Long> createAnnouncement(@Valid @RequestBody EvalAnnouncementSaveReqVO createReqVO) {
        return success(announcementService.createAnnouncement(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新公告发布")
    @PreAuthorize("@ss.hasPermission('eval:announcement:update')")
    public CommonResult<Boolean> updateAnnouncement(@Valid @RequestBody EvalAnnouncementSaveReqVO updateReqVO) {
        announcementService.updateAnnouncement(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除公告发布")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:delete')")
    public CommonResult<Boolean> deleteAnnouncement(@RequestParam("id") Long id) {
        announcementService.deleteAnnouncement(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得公告发布")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('eval:announcement:query')")
    public CommonResult<EvalAnnouncementRespVO> getAnnouncement(@RequestParam("id") Long id) {
        EvalAnnouncementDO announcement = announcementService.getAnnouncement(id);
        return success(BeanUtils.toBean(announcement, EvalAnnouncementRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得公告发布分页")
    @PreAuthorize("@ss.hasPermission('eval:announcement:query')")
    public CommonResult<PageResult<EvalAnnouncementRespVO>> getAnnouncementPage(@Valid EvalAnnouncementPageReqVO pageReqVO) {
        PageResult<EvalAnnouncementDO> pageResult = announcementService.getAnnouncementPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, EvalAnnouncementRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出公告发布 Excel")
    @PreAuthorize("@ss.hasPermission('eval:announcement:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportAnnouncementExcel(@Valid EvalAnnouncementPageReqVO exportReqVO,
                                        HttpServletResponse response) throws IOException {
        exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<EvalAnnouncementDO> list = announcementService.getAnnouncementList(exportReqVO);
        // 导出 Excel
        ExcelUtils.write(response, "公告发布.xls", "数据", EvalAnnouncementRespVO.class,
                BeanUtils.toBean(list, EvalAnnouncementRespVO.class));
    }

    @PutMapping("/publish")
    @Operation(summary = "发布公告")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:publish')")
    public CommonResult<Boolean> publishAnnouncement(@RequestParam("id") Long id) {
        announcementService.publishAnnouncement(id);
        return success(true);
    }

    @PutMapping("/withdraw")
    @Operation(summary = "撤回公告")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:withdraw')")
    public CommonResult<Boolean> withdrawAnnouncement(@RequestParam("id") Long id) {
        announcementService.withdrawAnnouncement(id);
        return success(true);
    }

    @PutMapping("/top")
    @Operation(summary = "置顶公告")
    @Parameter(name = "id", description = "编号", required = true)
    @Parameter(name = "topOrder", description = "置顶顺序", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:update')")
    public CommonResult<Boolean> topAnnouncement(@RequestParam("id") Long id, @RequestParam("topOrder") Integer topOrder) {
        announcementService.topAnnouncement(id, topOrder);
        return success(true);
    }

    @PutMapping("/cancel-top")
    @Operation(summary = "取消置顶")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:update')")
    public CommonResult<Boolean> cancelTopAnnouncement(@RequestParam("id") Long id) {
        announcementService.cancelTopAnnouncement(id);
        return success(true);
    }

    @PostMapping("/plan/{planId}/generate")
    @Operation(summary = "自动生成计划公告")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:create')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Long> generatePlanAnnouncement(@PathVariable("planId") Long planId,
                                                      @Valid @RequestBody EvalAnnouncementGenerateReqVO generateReqVO) {
        return success(announcementService.generatePlanAnnouncement(planId, generateReqVO));
    }

    @PostMapping("/plan/{planId}/generate-score")
    @Operation(summary = "自动生成成绩公告")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:create')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Long> generateScoreAnnouncement(@PathVariable("planId") Long planId,
                                                       @Valid @RequestBody EvalScoreAnnouncementGenerateReqVO generateReqVO) {
        return success(announcementService.generateScoreAnnouncement(planId, generateReqVO));
    }

    @GetMapping("/plan/{planId}")
    @Operation(summary = "获取计划相关公告")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @Parameter(name = "announcementType", description = "公告类型", required = false)
    @Parameter(name = "publishStatus", description = "发布状态", required = false)
    @PreAuthorize("@ss.hasPermission('eval:announcement:query')")
    public CommonResult<List<EvalAnnouncementRespVO>> getPlanAnnouncements(
            @PathVariable("planId") Long planId,
            @RequestParam(value = "announcementType", required = false) String announcementType,
            @RequestParam(value = "publishStatus", required = false) Integer publishStatus) {
        List<EvalAnnouncementRespVO> list = announcementService.getPlanAnnouncements(planId, announcementType, publishStatus);
        return success(list);
    }

    @GetMapping("/public")
    @Operation(summary = "获取公开公告列表")
    @Parameter(name = "announcementType", description = "公告类型", required = false)
    @Parameter(name = "keyword", description = "搜索关键词", required = false)
    public CommonResult<PageResult<EvalAnnouncementRespVO>> getPublicAnnouncements(
            @RequestParam(value = "announcementType", required = false) String announcementType,
            @RequestParam(value = "keyword", required = false) String keyword,
            @Valid EvalAnnouncementPageReqVO pageReqVO) {
        PageResult<EvalAnnouncementRespVO> pageResult = announcementService.getPublicAnnouncements(announcementType, keyword, pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/public/{announcementId}")
    @Operation(summary = "获取公开公告详情")
    @Parameter(name = "announcementId", description = "公告ID", required = true)
    public CommonResult<EvalAnnouncementRespVO> getPublicAnnouncement(@PathVariable("announcementId") Long announcementId) {
        EvalAnnouncementRespVO announcement = announcementService.getPublicAnnouncement(announcementId);
        return success(announcement);
    }

    @PostMapping("/{announcementId}/view")
    @Operation(summary = "记录公告查看")
    @Parameter(name = "announcementId", description = "公告ID", required = true)
    public CommonResult<Boolean> recordAnnouncementView(@PathVariable("announcementId") Long announcementId) {
        announcementService.recordAnnouncementView(announcementId);
        return success(true);
    }

    @GetMapping("/{announcementId}/statistics")
    @Operation(summary = "获取公告统计信息")
    @Parameter(name = "announcementId", description = "公告ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:query')")
    public CommonResult<EvalAnnouncementStatisticsRespVO> getAnnouncementStatistics(@PathVariable("announcementId") Long announcementId) {
        EvalAnnouncementStatisticsRespVO statistics = announcementService.getAnnouncementStatistics(announcementId);
        return success(statistics);
    }

    @PostMapping("/{announcementId}/notify")
    @Operation(summary = "发送公告通知")
    @Parameter(name = "announcementId", description = "公告ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:announcement:notify')")
    @ApiAccessLog(operateType = OTHER)
    public CommonResult<Boolean> sendAnnouncementNotification(@PathVariable("announcementId") Long announcementId,
                                                             @Valid @RequestBody EvalAnnouncementNotificationReqVO notificationReqVO) {
        announcementService.sendAnnouncementNotification(announcementId, notificationReqVO);
        return success(true);
    }

}
